package mdt.action;

import mdt.program.Displayer;
import org.tigris.gef.base.Editor;
import org.tigris.gef.base.Globals;
import org.tigris.gef.graph.MutableGraphSupport;
import org.tigris.gef.presentation.Fig;
import org.tigris.gef.presentation.FigAnchorNode;
import org.tigris.gef.presentation.FigEdge;
import org.tigris.gef.presentation.FigGroup;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by xiaobyu on 7/15/2016.
 */
public class GroupAction extends AbstractAction{

    public GroupAction() {
        super("Group");
        putValue(Action.SMALL_ICON, new ImageIcon(FontBoldAction.class.getResource("/resources/group-16.png")));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Editor ce = Globals.curEditor();
        List<Fig> selectedFigs = ce.getSelectionManager().getSelectedFigs();

        if (selectedFigs.size() < 2) return;

        List<Fig> existingFigGroups = new ArrayList<Fig>();
        Iterator<Fig> iter = selectedFigs.iterator();
        int edgeCount = 0;
        Rectangle bounds = selectedFigs.get(0).getBounds();
        List<Fig> linkedAddFigs = new ArrayList<>();
        while (iter.hasNext()) {
            Fig fig = iter.next();

            if (fig.getClass().isAssignableFrom(FigGroup.class)) {
                existingFigGroups.add(fig);
            } else if (fig instanceof FigEdge) {
                FigEdge edge = (FigEdge)fig;
                Fig src = edge.getSourceFigNode();
                Fig dst = edge.getDestFigNode();
                if (src instanceof FigAnchorNode
                        && dst instanceof FigAnchorNode
                        && !(src.getGroup() instanceof FigEdge)
                        && !(dst.getGroup() instanceof FigEdge)){
                    linkedAddFigs.add(edge.getSourceFigNode());
                    linkedAddFigs.add(edge.getDestFigNode());
                    continue;
                }
                iter.remove();
                edgeCount++;
            }

            bounds.add(fig.getBounds());
        }

        for (Fig fig : linkedAddFigs) {
            if (!selectedFigs.contains(fig)) {
                selectedFigs.add(fig);
            }
        }

        if (edgeCount > 0) {
            Displayer.instance().showWarningMessage(bounds,
                    "Non-free edge figures can't be grouped, detected edge count: " + edgeCount);
        }

        if (existingFigGroups.size() > 0) {
            Displayer.instance().showWarningMessage(bounds,
                    "Group figures cannot be nested, please ungroup\n selected group figures before grouping them");
            ce.getSelectionManager().deselectAll();
            ce.getSelectionManager().selectFigs(existingFigGroups);
            return;
        }

        FigGroup newGroup = new FigGroup();
        newGroup.setIntegrited(false);
        if (selectedFigs.size() > 1) {
            for (Fig fig : selectedFigs) {
                newGroup.addFig(fig);
                ce.remove(fig);
            }
            ce.add(newGroup);
        }

        MutableGraphSupport.enableSaveAction();
        ce.getSelectionManager().deselectAll();
        ce.getSelectionManager().select(newGroup);
    }
}
